package com.clothing.customization.service.impl;

import com.clothing.customization.dto.UserDTO;
import com.clothing.customization.dto.UserQueryDTO;
import com.clothing.customization.entity.User;
import com.clothing.customization.repository.UserRepository;
import com.clothing.customization.service.UserManagementService;
import jakarta.persistence.criteria.Predicate;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 用户管理服务实现类
 */
@Service
@RequiredArgsConstructor
public class UserManagementServiceImpl implements UserManagementService {
    
    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;
    
    @Override
    public Page<UserDTO> getUserList(UserQueryDTO queryDTO) {
        // 创建分页和排序条件
        PageRequest pageRequest = PageRequest.of(
            queryDTO.getPageNum() - 1,
            queryDTO.getPageSize(),
            Sort.by(Sort.Direction.DESC, "createTime")
        );
        
        // 创建查询条件
        Specification<User> specification = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            
            // 用户名模糊查询
            if (StringUtils.hasText(queryDTO.getUsername())) {
                predicates.add(cb.like(root.get("username"), "%" + queryDTO.getUsername() + "%"));
            }
            
            // 手机号模糊查询
            if (StringUtils.hasText(queryDTO.getPhone())) {
                predicates.add(cb.like(root.get("phone"), "%" + queryDTO.getPhone() + "%"));
            }
            
            // 状态精确查询
            if (queryDTO.getStatus() != null) {
                predicates.add(cb.equal(root.get("status"), queryDTO.getStatus()));
            }
            
            return cb.and(predicates.toArray(new Predicate[0]));
        };
        
        // 执行分页查询
        return userRepository.findAll(specification, pageRequest).map(this::convertToDTO);
    }
    
    @Override
    public UserDTO getUserDetail(Long id) {
        User user = userRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("用户不存在"));
        return convertToDTO(user);
    }
    
    @Override
    @Transactional
    public UserDTO createUser(UserDTO userDTO) {
        // 验证用户名是否已存在
        if (userRepository.existsByUsername(userDTO.getUsername())) {
            throw new IllegalArgumentException("用户名已存在");
        }
        
        // 验证手机号是否已存在
        if (StringUtils.hasText(userDTO.getPhone()) && userRepository.existsByPhone(userDTO.getPhone())) {
            throw new IllegalArgumentException("手机号已被注册");
        }
        
        // 验证邮箱是否已存在
        if (StringUtils.hasText(userDTO.getEmail()) && userRepository.existsByEmail(userDTO.getEmail())) {
            throw new IllegalArgumentException("邮箱已被注册");
        }
        
        User user = new User();
        BeanUtils.copyProperties(userDTO, user);
        // 设置默认密码
        user.setPassword(passwordEncoder.encode("123456"));
        
        return convertToDTO(userRepository.save(user));
    }
    
    @Override
    @Transactional
    public UserDTO updateUser(Long id, UserDTO userDTO) {
        User user = userRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("用户不存在"));
        
        // 验证用户名是否已被其他用户使用
        if (!user.getUsername().equals(userDTO.getUsername()) &&
                userRepository.existsByUsername(userDTO.getUsername())) {
            throw new IllegalArgumentException("用户名已存在");
        }
        
        // 验证手机号是否已被其他用户使用
        if (StringUtils.hasText(userDTO.getPhone()) &&
                !userDTO.getPhone().equals(user.getPhone()) &&
                userRepository.existsByPhone(userDTO.getPhone())) {
            throw new IllegalArgumentException("手机号已被注册");
        }
        
        // 验证邮箱是否已被其他用户使用
        if (StringUtils.hasText(userDTO.getEmail()) &&
                !userDTO.getEmail().equals(user.getEmail()) &&
                userRepository.existsByEmail(userDTO.getEmail())) {
            throw new IllegalArgumentException("邮箱已被注册");
        }
        
        // 更新用户信息
        BeanUtils.copyProperties(userDTO, user);
        return convertToDTO(userRepository.save(user));
    }
    
    @Override
    @Transactional
    public void deleteUser(Long id) {
        User user = userRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("用户不存在"));
        
        // 不允许删除管理员
        if ("admin".equals(user.getRole())) {
            throw new IllegalArgumentException("不能删除管理员用户");
        }
        
        userRepository.delete(user);
    }
    
    @Override
    @Transactional
    public UserDTO updateUserStatus(Long id, Integer status) {
        User user = userRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("用户不存在"));
        
        // 不允许禁用管理员
        if ("admin".equals(user.getRole()) && status == 0) {
            throw new IllegalArgumentException("不能禁用管理员用户");
        }
        
        user.setStatus(status);
        return convertToDTO(userRepository.save(user));
    }
    
    @Override
    @Transactional
    public void resetPassword(Long id, String newPassword) {
        User user = userRepository.findById(id)
                .orElseThrow(() -> new IllegalArgumentException("用户不存在"));
        
        user.setPassword(passwordEncoder.encode(newPassword));
        userRepository.save(user);
    }
    
    /**
     * 将实体对象转换为DTO
     */
    private UserDTO convertToDTO(User user) {
        UserDTO dto = new UserDTO();
        BeanUtils.copyProperties(user, dto);
        return dto;
    }
} 